<script setup lang="ts">
import { ref, computed } from 'vue';
import { useStitchingStore } from '../../stores/stitchingStore';
import { useUploadStore } from '../../stores/uploadStore';
import { validateStitchedImageSize } from '../../utils/validationUtils';
import imageStitchingService from '../../services/ImageStitchingService';
import { handleError, ValidationError, MemoryError, ProcessingError } from '../../utils/errorUtils';

const stitchingStore = useStitchingStore();
const uploadStore = useUploadStore();
const errorMessage = ref<string | null>(null);
const showError = ref(false);

// Compute estimated output size based on current options
const estimatedSize = computed(() => {
  const images = uploadStore.images.map(img => ({
    width: img.width,
    height: img.height
  }));

  const validation = validateStitchedImageSize(
    images,
    stitchingStore.stitchingOptions.spacing,
    stitchingStore.stitchingOptions.arrangement,
    stitchingStore.stitchingOptions.maxWidth,
    stitchingStore.stitchingOptions.maxHeight
  );

  return validation.estimatedSize || { width: 0, height: 0 };
});

// Validate if stitching is possible with current options
const isStitchingValid = computed(() => {
  if (uploadStore.images.length === 0) {
    return false;
  }

  const images = uploadStore.images.map(img => ({
    width: img.width,
    height: img.height
  }));

  const validation = validateStitchedImageSize(
    images,
    stitchingStore.stitchingOptions.spacing,
    stitchingStore.stitchingOptions.arrangement,
    stitchingStore.stitchingOptions.maxWidth,
    stitchingStore.stitchingOptions.maxHeight
  );

  if (!validation.valid) {
    return false;
  }

  return true;
});

async function startStitching() {
  // Clear previous error
  errorMessage.value = null;
  showError.value = false;

  if (uploadStore.images.length === 0) {
    errorMessage.value = '请先上传图片';
    showError.value = true;
    return;
  }

  // Validate stitching options
  const images = uploadStore.images.map(img => ({
    width: img.width,
    height: img.height
  }));

  const validation = validateStitchedImageSize(
    images,
    stitchingStore.stitchingOptions.spacing,
    stitchingStore.stitchingOptions.arrangement,
    stitchingStore.stitchingOptions.maxWidth,
    stitchingStore.stitchingOptions.maxHeight
  );

  if (!validation.valid) {
    errorMessage.value = validation.message || '拼接设置无效';
    showError.value = true;
    return;
  }

  stitchingStore.isStitching = true;

  try {
    // Start stitching process
    const stitchedImage = await imageStitchingService.stitchImages(
      uploadStore.images,
      stitchingStore.stitchingOptions,
      (progress) => {
        stitchingStore.stitchingProgress = progress;
      }
    );

    // Generate metadata
    const metadata = imageStitchingService.generateMetadata(
      uploadStore.images,
      stitchedImage,
      stitchingStore.stitchingOptions
    );

    // Update store
    stitchingStore.stitchedImage = stitchedImage;
    stitchingStore.metadata = metadata;
  } catch (error: any) {
    console.error('拼接图片失败:', error);

    // Handle different types of errors
    if (error instanceof MemoryError) {
      errorMessage.value = '内存不足，无法拼接这么多图片。请减少图片数量或降低图片分辨率。';
    } else if (error instanceof ValidationError) {
      errorMessage.value = error.message || '拼接设置无效，请检查参数。';
    } else if (error instanceof ProcessingError) {
      errorMessage.value = error.message || '拼接过程中出错，请重试。';
    } else {
      errorMessage.value = handleError(error);
    }

    showError.value = true;
  } finally {
    stitchingStore.isStitching = false;
  }
}
</script>

<template>
  <div class="stitching-controls">
    <h3>拼接设置</h3>
    <div class="control-group">
      <label for="arrangement">排列方式</label>
      <select id="arrangement" v-model="stitchingStore.stitchingOptions.arrangement">
        <option value="dynamic">动态布局 (会自动旋转图片)</option>
        <option value="grid">网格排列（弃用）</option>
        <option value="horizontal">水平排列（弃用）</option>
        <option value="vertical">垂直排列（弃用）</option>

      </select>
    </div>

    <div class="control-group">
      <label for="spacing">图片间距 (像素)</label>
      <input id="spacing" type="number" min="0" max="100" v-model.number="stitchingStore.stitchingOptions.spacing"
        @input="stitchingStore.stitchingOptions.spacing = 0">
    </div>

    <div class="control-group">
      <label for="bg-color">背景颜色</label>
      <input id="bg-color" type="color" v-model="stitchingStore.stitchingOptions.backgroundColor">
    </div>

    <div class="control-group" v-if="stitchingStore.stitchingOptions.arrangement === 'dynamic'">
      <!-- <div class="checkbox-control">
        <input 
          id="allow-rotation"
          type="checkbox"
          v-model="stitchingStore.stitchingOptions.allowRotation"
        >
        <label for="allow-rotation">允许旋转图片以优化布局</label>
      </div> -->
      <!-- <p class="help-text">旋转信息将被记录在元数据中，以便在还原时正确处理</p> -->

      <div class="target-size-control">
        <label for="target-size">目标尺寸 (像素)</label>
        <input id="target-size" type="number" min="1000" max="20000" step="1000"
          :value="stitchingStore.stitchingOptions.targetSize || 12000"
          @input="e => stitchingStore.stitchingOptions.targetSize = Number((e.target as HTMLInputElement).value)">
      </div>
    </div>

    <div v-if="uploadStore.images.length > 0" class="estimated-size">
      <p>预计输出尺寸: {{ estimatedSize.width }}x{{ estimatedSize.height }} 像素</p>
      <p v-if="!isStitchingValid" class="size-warning">
        警告: 拼接后的图片尺寸可能超过限制 (12000x12000 像素)
      </p>
    </div>

    <button class="stitch-button"
      :disabled="uploadStore.images.length === 0 || stitchingStore.isStitching || !isStitchingValid"
      @click="startStitching" aria-label="开始拼接图片" :aria-busy="stitchingStore.isStitching"
      :aria-disabled="uploadStore.images.length === 0 || !isStitchingValid">
      开始拼接
    </button>

    <div v-if="stitchingStore.isStitching" class="stitching-progress">
      <div class="loading-spinner">
        <div class="spinner"></div>
      </div>
      <p>拼接中...</p>
    </div>

    <div v-if="showError" class="error-message">
      <p>{{ errorMessage }}</p>
    </div>
  </div>
</template>

<style scoped>
.stitching-controls {
  margin-top: 2rem;
  padding: 1.5rem;
  background-color: #f5f5f5;
  border-radius: 8px;
}

h3 {
  margin-top: 0;
  margin-bottom: 1.5rem;
}

.control-group {
  margin-bottom: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

label {
  font-weight: 500;
}

select,
input[type="number"] {
  padding: 0.5rem;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 1rem;
}

input[type="color"] {
  width: 100%;
  height: 40px;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 2px;
}

.stitch-button {
  width: 100%;
  padding: 0.75rem;
  background-color: #4caf50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
  margin-top: 1rem;
}

.stitch-button:hover:not(:disabled) {
  background-color: #45a049;
}

.stitch-button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.stitching-progress {
  margin-top: 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

.loading-spinner {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 0.5rem;
}

.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(76, 175, 80, 0.3);
  border-radius: 50%;
  border-top-color: #4caf50;
  animation: spin 1s ease-in-out infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.estimated-size {
  margin: 1rem 0;
  padding: 0.75rem;
  background-color: #e8f5e9;
  border-radius: 4px;
  font-size: 0.9rem;
}

.estimated-size p {
  margin: 0.25rem 0;
}

.size-warning {
  color: #f44336;
  font-weight: 500;
}

.checkbox-control {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.checkbox-control input[type="checkbox"] {
  width: 18px;
  height: 18px;
}

.help-text {
  font-size: 0.85rem;
  color: #666;
  margin: 0.25rem 0;
}

.target-size-control {
  margin-top: 0.75rem;
}

.error-message {
  margin-top: 1rem;
  padding: 0.75rem;
  background-color: #ffebee;
  border: 1px solid #ffcdd2;
  border-radius: 4px;
  color: #c62828;
}
</style>